import React, { useState, useEffect, useRef } from 'react'
import { ImageViewer, Toast } from 'antd-mobile'
import { useNavigate } from 'react-router-dom'
import { 
  PictureOutline, 
  SmileOutline, 
  VideoOutline, 
  AudioOutline,
  SendOutline,
  AddOutline
} from 'antd-mobile-icons'
import './index.css'

// 消息类型
const MessageType = {
  TEXT: 'text',
  IMAGE: 'image',
  EMOJI: 'emoji',
  AUDIO: 'audio',
  VIDEO: 'video',
  FILE: 'file'
} as const

type MessageTypeValue = typeof MessageType[keyof typeof MessageType]

// 消息接口
interface Message {
  id: number
  type: MessageTypeValue
  content: string
  isUser: boolean
  timestamp: string
  fileUrl?: string
  fileName?: string
  fileSize?: number
  duration?: number
  thumbnail?: string
}

// 表情数据
const emojis = [
  '😀', '😃', '😄', '😁', '😆', '😅', '😂', '🤣',
  '😊', '😇', '🙂', '🙃', '😉', '😌', '😍', '🥰',
  '😘', '😗', '😙', '😚', '😋', '😛', '😝', '😜',
  '🤪', '🤨', '🧐', '🤓', '😎', '🤩', '🥳', '😏'
]

function Message() {
  const navigate = useNavigate()
  
  const [messages, setMessages] = useState<Message[]>([
    {
      id: 1,
      type: MessageType.TEXT,
      content: '您好！我是AI助手，有什么可以帮助您的吗？',
      isUser: false,
      timestamp: '10:00'
    }
  ])
  
  const [inputText, setInputText] = useState('')
  const [isStreaming, setIsStreaming] = useState(false)
  const [streamingIndicator, setStreamingIndicator] = useState('')
  const [showEmojiPanel, setShowEmojiPanel] = useState(false)
  const [showMediaPanel, setShowMediaPanel] = useState(false)
  const [isRecording, setIsRecording] = useState(false)
  const [recordingTime, setRecordingTime] = useState(0)
  // 人工客服相关
  const [isHumanAgent, setIsHumanAgent] = useState(false)
  const [isTransferring, setIsTransferring] = useState(false)
  
  const messageListRef = useRef<HTMLDivElement>(null)
  const abortRef = useRef<AbortController | null>(null)
  const fileInputRef = useRef<HTMLInputElement>(null)
  const audioRecorderRef = useRef<MediaRecorder | null>(null)
  const recordingTimerRef = useRef<number | null>(null)

  // 生成不重复的消息ID，避免同毫秒创建导致覆盖
  const generateMessageId = (): number => Date.now() + Math.floor(Math.random() * 1000000)

  // API配置 - 从环境变量读取
  const API_ENDPOINT = '/youdao'
  const API_KEY = import.meta.env.VITE_YOUDAO_API_KEY || ''
  const YOUDAO_MODEL = (import.meta.env.VITE_YOUDAO_MODEL || 'deepseek').trim()
  // 有道控制台：应用ID + 密钥/包名/Bundle ID
  const APP_ID = import.meta.env.VITE_YOUDAO_APP_ID || ''
  const APP_KEY = import.meta.env.VITE_YOUDAO_APP_KEY || ''

  // 自动滚动到底部
  const scrollToBottom = () => {
    if (messageListRef.current) {
      messageListRef.current.scrollTop = messageListRef.current.scrollHeight
    }
  }

  useEffect(() => {
    scrollToBottom()
  }, [messages])

  // 启动时查询模型列表，帮助定位 USER_WRONG_MODEL
  useEffect(() => {
    const checkModels = async () => {
      if (!API_KEY) return
      try {
        const resp = await fetch('/youdao_models', {
          headers: {
            'Authorization': `Bearer ${API_KEY}`,
            ...(APP_ID ? { 'X-App-Id': APP_ID } : {}),
            ...(APP_KEY ? { 'X-App-Key': APP_KEY } : {})
          }
        })
        const text = await resp.text().catch(() => '')
        console.log('Youdao /models 返回：', text)
      } catch (e) {
        console.debug('查询模型列表失败', e)
      }
    }
    checkModels()
  }, [])

  // 录音计时器
  useEffect(() => {
    if (isRecording) {
      recordingTimerRef.current = window.setInterval(() => {
        setRecordingTime(prev => prev + 1)
      }, 1000)
    } else {
      if (recordingTimerRef.current) {
        clearInterval(recordingTimerRef.current)
        recordingTimerRef.current = null
      }
      setRecordingTime(0)
    }

    return () => {
      if (recordingTimerRef.current) {
        clearInterval(recordingTimerRef.current)
      }
    }
  }, [isRecording])

  // 开始录音
  const startRecording = async () => {
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
      const recorder = new MediaRecorder(stream)
      const chunks: Blob[] = []

      recorder.ondataavailable = (e) => {
        if (e.data.size > 0) {
          chunks.push(e.data)
        }
      }

      recorder.onstop = () => {
        const blob = new Blob(chunks, { type: 'audio/wav' })
        const url = URL.createObjectURL(blob)
        
        const newMessage: Message = {
          id: generateMessageId(),
          type: MessageType.AUDIO,
          content: '语音消息',
          isUser: true,
          timestamp: new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }),
          fileUrl: url,
          fileName: `语音消息_${new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })}.wav`,
          fileSize: blob.size,
          duration: Math.max(recordingTime, 1)
        }
        
        setMessages(prev => [...prev, newMessage])
        setIsRecording(false)
        stream.getTracks().forEach(track => track.stop())
      }

      audioRecorderRef.current = recorder
      recorder.start()
      setIsRecording(true)
      setShowMediaPanel(false)
    } catch (error) {
      console.error('录音失败:', error)
      Toast.show('无法访问麦克风')
    }
  }

  // 停止录音
  const stopRecording = () => {
    if (audioRecorderRef.current && isRecording) {
      audioRecorderRef.current.stop()
    }
  }

  // 处理文件上传（图片/视频/通用文件）
  const handleFileUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const files = event.target.files
    if (!files || files.length === 0) return

    const file = files[0]
    const maxSize = 50 * 1024 * 1024 // 50MB
    
    if (file.size > maxSize) {
      Toast.show('文件大小不能超过50MB')
      return
    }

    const fileUrl = URL.createObjectURL(file)
    let messageType: MessageTypeValue
    let content: string

    if (file.type.startsWith('image/')) {
      messageType = MessageType.IMAGE
      content = '图片消息'
    } else if (file.type.startsWith('video/')) {
      messageType = MessageType.VIDEO
      content = '视频消息'
    } else {
      // 其余类型按通用文件处理
      messageType = MessageType.FILE
      content = '文件消息'
    }

    const newMessage: Message = {
      id: generateMessageId(),
      type: messageType,
      content,
      isUser: true,
      timestamp: new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }),
      fileUrl,
      fileName: file.name,
      fileSize: file.size
    }

    setMessages(prev => [...prev, newMessage])
    setShowMediaPanel(false)
    
    if (fileInputRef.current) {
      fileInputRef.current.value = ''
    }

    Toast.show('文件上传成功')
  }

  // 选择表情
  const selectEmoji = (emoji: string) => {
    setInputText(prev => prev + emoji)
    setShowEmojiPanel(false)
  }

  // 发送表情消息
  const sendEmojiMessage = (emoji: string) => {
    const newMessage: Message = {
      id: generateMessageId(),
      type: MessageType.EMOJI,
      content: emoji,
      isUser: true,
      timestamp: new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })
    }

    setMessages(prev => [...prev, newMessage])
    setShowEmojiPanel(false)

    // 给表情消息一个友好的回复
    setTimeout(() => {
      const aiMessage: Message = {
        id: Date.now(),
        type: MessageType.TEXT,
        content: '收到您的表情了！😊 有什么可以帮助您的吗？',
        isUser: false,
        timestamp: new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })
      }
      setMessages(prev => [...prev, aiMessage])
    }, 500)
  }

  // 发送文本消息
  const sendTextMessage = (text: string) => {
    if (!text.trim()) return

    const isOnlyEmoji = /^[\u{1F600}-\u{1F64F}\u{1F300}-\u{1F5FF}\u{1F680}-\u{1F6FF}\u{1F1E0}-\u{1F1FF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}\s]+$/u.test(text.trim())
    
    let messageType: MessageTypeValue = MessageType.TEXT
    if (isOnlyEmoji) {
      messageType = MessageType.EMOJI
    }

    const newMessage: Message = {
      id: generateMessageId(),
      type: messageType,
      content: text,
      isUser: true,
      timestamp: new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })
    }

    setMessages(prev => [...prev, newMessage])
    setInputText('')

    if (isOnlyEmoji) {
      setTimeout(() => {
        const aiMessage: Message = {
          id: Date.now(),
          type: MessageType.TEXT,
          content: '收到您的表情了！😊 有什么可以帮助您的吗？',
          isUser: false,
          timestamp: new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })
        }
        setMessages(prev => [...prev, aiMessage])
      }, 500)
    } else {
      sendToAI(text)
    }
  }

  // 发送消息到AI - 核心功能
  const sendToAI = async (userText: string) => {
    if (!API_KEY) {
      Toast.show('请先配置API密钥，在 .env 文件中设置 VITE_YOUDAO_API_KEY')
      return
    }

    // 先插入一条空的AI消息
    const id = generateMessageId()
    setMessages(prev => [
      ...prev,
      {
        id,
        type: MessageType.TEXT,
        content: '正在思考中...',
        isUser: false,
        timestamp: new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })
      }
    ])

    try {
      abortRef.current?.abort()
      abortRef.current = new AbortController()
      setIsStreaming(true)
      
      // 构建请求数据（增加 system 消息，确保 role 值符合要求）
      const payload = {
        model: YOUDAO_MODEL,
        messages: [
          { role: 'system', content: '你是一个中文智能助手。默认使用简体中文进行回答，语言自然、简洁、有条理；保持用户提供的列表/代码/表格等格式；除非用户要求其它语言或格式。' },
          { role: 'user', content: userText }
        ],
        stream: true,
        temperature: 0.7,
        max_tokens: 2000
      }

      let response = await fetch(API_ENDPOINT, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${API_KEY}`,
          ...(APP_ID ? { 'X-App-Id': APP_ID, 'App-Id': APP_ID } : {}),
          ...(APP_KEY ? { 'X-App-Key': APP_KEY, 'App-Key': APP_KEY, 'appKey': APP_KEY } : {})
        },
        body: JSON.stringify(payload),
        signal: abortRef.current.signal
      })

      if (!response.ok) {
        const errorText = await response.text().catch(() => '')
        console.error('LLM网关非2xx响应', {
          status: response.status,
          statusText: response.statusText,
          body: errorText
        })
        // 若为模型不匹配，自动尝试备用模型
        if (response.status === 422 && /USER_WRONG_MODEL/i.test(errorText)) {
          const fallbackModel = YOUDAO_MODEL.includes('coder') ? 'deepseek-chat' : 'deepseek-coder'
          console.warn(`检测到 USER_WRONG_MODEL，改用备用模型: ${fallbackModel}`)
          const resp2 = await fetch(API_ENDPOINT, {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
              'Authorization': `Bearer ${API_KEY}`,
              ...(APP_ID ? { 'X-App-Id': APP_ID, 'App-Id': APP_ID } : {}),
              ...(APP_KEY ? { 'X-App-Key': APP_KEY, 'App-Key': APP_KEY, 'appKey': APP_KEY } : {})
            },
            body: JSON.stringify({ ...payload, model: fallbackModel }),
            signal: abortRef.current.signal
          })
          if (!resp2.ok) {
            const err2 = await resp2.text().catch(() => '')
            throw new Error(`HTTP ${resp2.status}: ${err2 || resp2.statusText}`)
          }
          response = resp2
        } else {
          throw new Error(`HTTP ${response.status}: ${errorText || response.statusText}`)
        }
      }

      if (!response.body) {
        throw new Error('响应体为空')
      }

      // 处理流式响应
      const reader = response.body.getReader()
      const decoder = new TextDecoder('utf-8')
      let buffer = ''
      let fullContent = ''
      let isFirstChunk = true
      let chunkCount = 0

      while (true) {
        const { done, value } = await reader.read()
        if (done) break
        
        buffer += decoder.decode(value, { stream: true })
        const parts = buffer.split('\n\n')
        buffer = parts.pop() || ''

        for (const chunk of parts) {
          const line = chunk.trim()
          if (!line.startsWith('data:')) continue
          
          const dataStr = line.replace(/^data:\s*/, '')
          if (dataStr === '[DONE]') continue
          
                     try {
             const json = JSON.parse(dataStr)
             // 修复：使用 reasoning_content 而不是 content
             const delta = json?.choices?.[0]?.delta?.reasoning_content || json?.choices?.[0]?.delta?.content
             
             // 调试信息
             if (chunkCount < 3) {
               console.log('流式数据块:', { 
                 chunkCount, 
                 delta, 
                 hasReasoningContent: !!json?.choices?.[0]?.delta?.reasoning_content,
                 hasContent: !!json?.choices?.[0]?.delta?.content
               })
             }
             
             if (typeof delta === 'string' && delta.length > 0) {
               chunkCount++
               // 如果是第一个chunk，移除"正在思考中..."
               if (isFirstChunk) {
                 fullContent = delta
                 isFirstChunk = false
               } else {
                 fullContent += delta
               }
               
               // 更新流式指示器
               setStreamingIndicator(`正在回复中... (${chunkCount} 个数据块)`)
               
               setMessages(prev => prev.map(m => 
                 m.id === id ? { ...m, content: fullContent } : m
               ))
               scrollToBottom()
             }
           } catch (error) {
             console.debug('解析SSE数据失败:', error)
           }
        }
      }

      // 如果流式响应失败，尝试非流式
      if (!fullContent) {
        const data = await response.json()
        const content = data?.choices?.[0]?.message?.content || data?.choices?.[0]?.message?.reasoning_content || '抱歉，暂时无法获取回复。'
        setMessages(prev => prev.map(m => 
          m.id === id ? { ...m, content } : m
        ))
      }

    } catch (error) {
      console.error('API请求失败:', error)
      
      let errorMessage = '抱歉，请稍后再试。'
      if (error instanceof Error) {
        if (error.message.includes('401')) {
          errorMessage = 'API密钥无效，请检查配置。'
        } else if (error.message.includes('404')) {
          errorMessage = '服务暂时不可用，请稍后再试。'
        } else if (error.message.includes('aborted')) {
          errorMessage = '已取消回复。'
        }
      }
      
      setMessages(prev => prev.map(m => 
        m.id === id ? { ...m, content: errorMessage } : m
      ))
    } finally {
      setIsStreaming(false)
      setStreamingIndicator('')
    }
  }

  // 处理发送
  const handleSend = () => {
    if (inputText.trim()) {
      sendTextMessage(inputText)
    }
  }

  // 处理按键
  const handleKeyPress = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault()
      handleSend()
    }
  }

  // 停止AI回复
  const handleStop = () => {
    abortRef.current?.abort()
    setIsStreaming(false)
  }

  // 转接到人工客服
  const transferToHuman = () => {
    if (isHumanAgent || isTransferring) return
    setIsTransferring(true)
    const transferMsg: Message = {
      id: generateMessageId(),
      type: MessageType.TEXT,
      content: '正在为您转接人工客服，请稍候…',
      isUser: false,
      timestamp: new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })
    }
    setMessages(prev => [...prev, transferMsg])
    setTimeout(() => {
      const readyMsg: Message = {
        id: generateMessageId(),
        type: MessageType.TEXT,
        content: '已为您接入人工客服（在线）。',
        isUser: false,
        timestamp: new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })
      }
      setMessages(prev => [...prev, readyMsg])
      setIsHumanAgent(true)
      setIsTransferring(false)
      // 停止AI流式（如果正在进行）
      handleStop()
    }, 1200)
  }

  // 结束人工客服，回到AI
  const backToAI = () => {
    if (!isHumanAgent) return
    setIsHumanAgent(false)
    const backMsg: Message = {
      id: generateMessageId(),
      type: MessageType.TEXT,
      content: '已为您恢复 AI 客服服务。',
      isUser: false,
      timestamp: new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })
    }
    setMessages(prev => [...prev, backMsg])
  }

  // 清理资源
  useEffect(() => {
    return () => {
      if (recordingTimerRef.current) window.clearInterval(recordingTimerRef.current)
      abortRef.current?.abort()
    }
  }, [])

  // 渲染消息内容
  const renderMessageContent = (message: Message) => {
    switch (message.type) {
      case MessageType.TEXT:
        return <div className="message-text">{message.content}</div>
      
      case MessageType.IMAGE:
        return (
          <div className="message-image">
            <img 
              src={message.fileUrl} 
              alt="图片消息"
              onClick={() => ImageViewer.show({ image: message.fileUrl! })}
            />
            {message.fileName && (
              <div className="file-info">
                <span className="file-name">{message.fileName}</span>
                {message.fileSize && (
                  <span className="file-size">{(message.fileSize / 1024 / 1024).toFixed(2)} MB</span>
                )}
              </div>
            )}
          </div>
        )
      
      case MessageType.EMOJI:
        return <div className="message-emoji">{message.content}</div>
      
      case MessageType.AUDIO:
        return (
          <div className="message-audio">
            <div className="audio-player">
              <div className="audio-icon">🎵</div>
              <div className="audio-controls">
                <audio src={message.fileUrl} controls>
                  您的浏览器不支持音频播放
                </audio>
              </div>
              <div className="audio-info">
                <div className="audio-duration">{message.duration || 0}s</div>
              </div>
            </div>
            {message.fileName && (
              <div className="audio-file-info">
                <span className="audio-file-name">{message.fileName}</span>
                {message.fileSize && (
                  <span className="audio-file-size">{(message.fileSize / 1024 / 1024).toFixed(2)} MB</span>
                )}
              </div>
            )}
          </div>
        )
      
      case MessageType.VIDEO:
        return (
          <div className="message-video">
            <video controls src={message.fileUrl}>
              您的浏览器不支持视频播放
            </video>
            {message.fileName && (
              <div className="file-info">
                <span className="file-name">{message.fileName}</span>
                {message.fileSize && (
                  <span className="file-size">{(message.fileSize / 1024 / 1024).toFixed(2)} MB</span>
                )}
              </div>
            )}
          </div>
        )
      
      case MessageType.FILE:
        return (
          <div className="message-file">
            <div className="file-row">
              <div className="file-meta">
                <span className="file-icon">📄</span>
                <span className="file-name">{message.fileName || '文件'}</span>
                {message.fileSize && (
                  <span className="file-size">{(message.fileSize / 1024).toFixed(1)} KB</span>
                )}
              </div>
              {message.fileUrl && (
                <a className="file-download" href={message.fileUrl} download={message.fileName || 'file'}>
                  下载
                </a>
              )}
            </div>
          </div>
        )
      
      default:
        return <div className="message-text">{message.content}</div>
    }
  }

  return (
    <div className="message-container">
      {/* 头部 */}
      <div className="message-header">
        <div className="header-left">
          <button 
            className="back-btn"
            onClick={() => navigate(-1)}
            title="返回"
          >
            ←
          </button>
          <h3>AI智能助手</h3>
        </div>
        <span className="status">在线</span>
        <div className="agent-controls" style={{ marginLeft: 'auto', display: 'flex', gap: 8 }}>
          <span className="agent-status">当前客服：{isHumanAgent ? '人工' : 'AI'}</span>
          {!isHumanAgent ? (
            <button className="agent-btn" onClick={transferToHuman} disabled={isTransferring}>
              {isTransferring ? '正在转接…' : '转人工'}
            </button>
          ) : (
            <button className="agent-btn" onClick={backToAI}>结束人工</button>
          )}
        </div>
      </div>

      {/* 消息列表 */}
      <div className="message-list" ref={messageListRef}>
        {messages.map((message) => (
          <div key={message.id} className={`message-item ${message.isUser ? 'user' : 'service'}`}>
            {!message.isUser && (
              <div className="avatar service-avatar">
                <span>AI</span>
              </div>
            )}
            <div className="message-content">
              {renderMessageContent(message)}
              <div className="message-time">{message.timestamp}</div>
            </div>
            {message.isUser && (
              <div className="avatar user-avatar">
                <span>我</span>
              </div>
            )}
          </div>
        ))}
      </div>

      {/* 表情面板 */}
      {showEmojiPanel && (
        <div className="emoji-panel">
          <div className="emoji-grid">
            {emojis.map((emoji, index) => (
              <span 
                key={index} 
                className="emoji-item"
                onClick={() => selectEmoji(emoji)}
                onDoubleClick={() => sendEmojiMessage(emoji)}
                title="单击添加到输入框，双击直接发送"
              >
                {emoji}
              </span>
            ))}
          </div>
          <div className="emoji-tip">
            单击添加到输入框，双击直接发送
          </div>
        </div>
      )}

      {/* 媒体选择面板 */}
      {showMediaPanel && (
        <div className="media-panel">
          <div className="media-options">
            <div className="media-option" onClick={() => fileInputRef.current?.click()}>
              <PictureOutline />
              <span>图片</span>
            </div>
            <div className="media-option" onClick={() => fileInputRef.current?.click()}>
              <VideoOutline />
              <span>视频</span>
            </div>
            {/* 新增：通用文件上传 */}
            <div className="media-option" onClick={() => fileInputRef.current?.click()}>
              <AddOutline />
              <span>文件</span>
            </div>
            <div className="media-option" onClick={startRecording}>
              <AudioOutline />
              <span>录音</span>
            </div>
          </div>
        </div>
      )}

      {/* 录音状态 */}
      {isRecording && (
        <div className="recording-overlay">
          <div className="recording-content">
            <div className="recording-icon">🎤</div>
            <div className="recording-text">正在录音... {recordingTime}s</div>
            <button className="stop-recording" onClick={stopRecording}>
              停止录音
            </button>
          </div>
        </div>
      )}

      {/* 输入区域 */}
      <div className="message-input-area">
        <div className="input-container">
          <button 
            className="media-btn"
            onClick={() => setShowMediaPanel(!showMediaPanel)}
          >
            <AddOutline />
          </button>
          
          <div className="text-input-container">
            <textarea
              value={inputText}
              onChange={(e) => setInputText(e.target.value)}
              onKeyPress={handleKeyPress}
              placeholder="请输入您的问题..."
              rows={1}
              className="message-input"
            />
          </div>
          
          <button 
            className="emoji-btn"
            onClick={() => setShowEmojiPanel(!showEmojiPanel)}
          >
            <SmileOutline />
          </button>
          
          <button 
            className="send-btn"
            onClick={handleSend}
            disabled={!inputText.trim()}
          >
            <SendOutline />
          </button>
        </div>
        
        {/* 停止AI回复按钮 */}
        {isStreaming && (
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 8 }}>
            <button className="stop-btn" onClick={handleStop}>
              停止回复
            </button>
            {streamingIndicator && (
              <span style={{ fontSize: 12, color: '#666' }}>
                {streamingIndicator}
              </span>
            )}
          </div>
        )}
      </div>

      {/* 隐藏的文件输入 */}
      <input
        ref={fileInputRef}
        type="file"
        accept="*/*"
        onChange={handleFileUpload}
        style={{ display: 'none' }}
      />
    </div>
  )
}

export default Message
